/*
 * @Description:
 * @Author:
 * @Date: 2024-12-07 09:17:36
 * @LastEditTime: 2025-02-16 21:05:23
 * @LastEditors: XXX
 */
import type { ActionContext, ActionTree } from "vuex";
import type { UserState } from "./state";
import type { RootState } from "@/store";
import { UserActionTypes } from "./action-types";
import type { Mutations } from "./mutations";
import { removeToken, setToken } from "@/utils/cookies";
import { UserMutationTypes } from "./mutation-types";
import router, { resetRouter } from "@/router";
import { useStore } from '@/store'
import { PermissionActionType } from "../permission/action-types";
import { state } from "./state";
import type { RouteRecordRaw } from "vue-router";
import { loginRequest, userInfoRequest } from '@/apis/user'

type AugmentedActionContext = {
  commit<K extends keyof Mutations> (
    key: K,
    payload: Parameters<Mutations[K]>[1]
  ): ReturnType<Mutations[K]>
} & Omit<ActionContext<UserState, RootState>, 'commit'>

export interface Actions {
  [UserActionTypes.ACTION_LOGIN] (
    { commit }: AugmentedActionContext,
    userInfo: { username: string, password: string }
  ): void

  [UserActionTypes.ACTION_RESET_TOKEN] (
    { commit }: AugmentedActionContext
  ): void

  [UserActionTypes.ACTION_LOGIN_OUT] (
    { commit }: AugmentedActionContext
  ): void

  [UserActionTypes.ACTION_GET_USER_INFO] (
    { commit }: AugmentedActionContext
  ): void
}

export const actions: ActionTree<UserState, RootState> & Actions = {
  async [UserActionTypes.ACTION_LOGIN] (
    { commit }: AugmentedActionContext,
    userInfo: { username: string, password: string }
  ) {
    console.log('userInfo :>> ', userInfo);
    let { username, password } = userInfo
    username = username.trim()
    await loginRequest({ username, password }).then(async res => {
      if (res?.code === 0 && res.data.accessToken) {
        const accessToken = res.data.accessToken
        setToken(accessToken)
        commit(UserMutationTypes.SET_TOKEN, accessToken)
      }
    }).catch(err => {
      console.log(err)
    })
  },

  [UserActionTypes.ACTION_RESET_TOKEN] (
    { commit }: AugmentedActionContext
  ) {
    removeToken()
    commit(UserMutationTypes.SET_TOKEN, '')
    commit(UserMutationTypes.SET_ROLES, [])
  },

  [UserActionTypes.ACTION_LOGIN_OUT] (
    { commit }: AugmentedActionContext
  ) {
    console.log(commit)
    removeToken()
    commit(UserMutationTypes.SET_TOKEN, '')
    resetRouter()
  },

  async [UserActionTypes.ACTION_CHANGE_ROLES] (
    { commit }: AugmentedActionContext,
    role: string
  ) {
    const token = `${role}-token`
    const store = useStore()
    commit(UserMutationTypes.SET_TOKEN, token)
    setToken(token)
    await store.dispatch(UserActionTypes.ACTION_GET_USER_INFO, undefined)
    store.dispatch(PermissionActionType.ACTION_SET_ROUTES, state.roles)
    store.state.permission.dynamicRoutes.forEach((item: RouteRecordRaw) => {
      router.addRoute(item)
    })
  },

  async [UserActionTypes.ACTION_GET_USER_INFO] (
    { commit }: AugmentedActionContext
  ) {
    if (state.token === '') {
      throw Error('token is undefined')
    }

    await userInfoRequest().then(res => {
      if (res?.code === 0) {
        commit(UserMutationTypes.SET_ROLES, res.data.roles)
        commit(UserMutationTypes.SET_NAME, res.data.name)
        commit(UserMutationTypes.SET_AVATAR, res.data.avatar)
        commit(UserMutationTypes.SET_INTRODUCTION, res.data.introduction)
        commit(UserMutationTypes.SET_EMAIL, res.data.email)
        return res
      } else {
        throw Error('Verification failed, please login again.')
      }
    })
  }
}
